﻿using System;
using Basic;
using Interface;
using UnityEngine;

namespace Client
{
    /// <summary>
    /// UI基类
    /// </summary>
    public class UIBase : AsyncObject
    {
        /// <summary>
        /// UI标识
        /// </summary>
        public readonly string UIKey;

        protected UIBase(string uiKey)
        {
            this.UIKey = uiKey;
        }

        /// <summary>
        /// 表现界面
        /// </summary>
        protected UIVisual Visual
        {
            get;
            private set;
        }

        /// <summary>
        /// 加载Visual是否已经完成
        /// </summary>
        protected bool m_LoadVisualActionDone = false;
         
        /// <summary>
        /// 开始加载界面Visual
        /// </summary>
        /// <param name="callback"></param>
        public void StartLoadVisual(Action<UIBase> callback)
        {
            var assetKey = UIKey;
            if (!this.StartAsyncCall())
            {
                AsyncActionHelper.Instance.DoActionNextFrame(() =>
                {
                    if (callback != null)
                    {
                        callback(this);
                    }
                });
                return;
            }

            Global.AssetManager.LoadGameObjectAsync(assetKey, (obj) =>
            {
                UIVisual visual = null;
                if (obj != null)
                {
                    visual = obj.GetComponent<UIVisual>();
                    if (visual == null)
                    {
                        Log.Error("UIBase.StartLoadVisual ui prefab not has UIVisual comp {0}", UIKey);
                        Global.AssetManager.OnGameObjectUseEnd(obj);
                    }
                }
                Visual = visual;
                m_LoadVisualActionDone = true;

                OnVisualLoaded();

                try
                {
                    if (callback != null)
                    {
                        callback(this);
                    }
                }
                catch (Exception ex)
                {
                    Log.Error("UIBase.StartLoadVisual callback get exception {0} {1}", UIKey, ex);
                }

                this.OnAsyncCallOver();
            });
        }

        /// <summary>
        /// 界面异步加载完成，一次使用期间，仅会触发一次
        /// 派生类中重载时，本方法放在开头执行
        /// </summary>
        protected virtual void OnVisualLoaded()
        {
            Log.Debug("UIBase.OnVisualLoaded {0} InUsing[{1}] Visual[{2}]", UIKey, InUsing, Visual != null);

            if (!InUsing)
            {
                return;
            }

            if (Visual == null)
            {
                SetInUsing(false);
            }
        }

        /// <summary>
        /// 使用前重置，与DoSafeClear一起，构成了起始区间
        /// 由UIManager调用
        /// </summary>
        public virtual void ResetForUse()
        {
            this.SetInUsing(true);
        }

        /// <summary>
        /// 使用完毕清理
        /// 派生类中重载时，本方法放在结尾执行
        /// </summary>
        protected override void DoSafeClear()
        {
            if (Visual != null)
            {
                Global.AssetManager.OnGameObjectUseEnd(Visual.gameObject);
                Visual = null;
            }
            m_LoadVisualActionDone = false;

            Global.UIManager.OnUIBaseUseEnd(this);
        }

        /// <summary>
        /// 设置父节点
        /// </summary>
        /// <param name="parent"></param>
        public void SetParent(Transform parent)
        {
            if (Visual != null)
            {
                Visual.SetParent(parent);
            }
        }

        /// <summary>
        /// 显示界面，与Hide是一对。可根据实际情况，触发多次。
        /// </summary>
        public virtual void Show()
        {
            Log.Debug("UIBase.Show {0} {1}", UIKey, m_LoadVisualActionDone);
            if (Visual != null)
            {
                Visual.DoAppear(null, true);
                OnShown();
            }
        }

        /// <summary>
        /// 隐藏界面
        /// </summary>
        public virtual void Hide()
        {
            Log.Debug("UIBase.Hide {0} {1}", UIKey, m_LoadVisualActionDone);
            if (Visual != null)
            {
                Visual.DoDisappear(null, true);
                OnHidden();
            }
        }

        /// <summary>
        /// 显示事件，与OnHidden是一对
        /// </summary>
        protected virtual void OnShown()
        {
        }

        /// <summary>
        /// 隐藏事件
        /// </summary>
        protected virtual void OnHidden()
        {
        }
    }
}
